package drds.plus.api;

import drds.plus.common.jdbc.Parameters;
import drds.plus.common.jdbc.SetParameterMethod;
import drds.plus.common.jdbc.SetParameterMethodAndArgs;
import drds.plus.executor.ExecuteContext;
import drds.plus.executor.cursor.cursor.impl.result_cursor.ResultCursor;

import java.math.BigDecimal;
import java.sql.*;

public class PreparedParseAndExecute extends Execute {

    // 参数列表到参数上下文的映射 如 1:columnName 2：'2011-11-11'
    protected Parameters parameters = new Parameters();
    protected int autoGeneratedKeys = -1;

    public PreparedParseAndExecute(SessionManager ds, SessionImpl conn, String sql, ExecuteContext ec) {
        super(ds, conn, sql, ec);
    }

    public boolean execute() throws SQLException {
        return super.executeInternal(sql, autoGeneratedKeys);
    }

    public ResultCursor executeQuery() throws SQLException {
        return this.executeQuery(sql);
    }

    public ResultCursor executeQuery(String sql) throws SQLException {
        checkClosed();
        ensureResultSetIsEmpty();
        currentResultSet = this.session.executeSQL(this.executeContext, sql, parameters, this, extraCmd);
        return currentResultSet;
    }

    public int executeUpdate() throws SQLException {
        return executeUpdateInternal(sql, autoGeneratedKeys);
    }

    protected int executeUpdateInternal(String sql, int autoGeneratedKeys) throws SQLException {
        checkClosed();
        ensureResultSetIsEmpty();
        executeContext.setAutoGeneratedKeys(autoGeneratedKeys);

        currentResultSet = this.session.executeSQL(this.executeContext, sql, parameters, this, extraCmd);
        return 0;// ((RowDataSet) resultSetWrapper).getAffectRows();
    }

    // 数据库从0开始，jdbc规范从1开始，jdbc到数据库要减一

    public void setInt(int parameterIndex, int x) throws SQLException {
        parameters.getIndexToSetParameterMethodAndArgsMap().put(parameterIndex, new SetParameterMethodAndArgs(SetParameterMethod.setInt, new Object[]{parameterIndex, x}));
    }

    public void setLong(int parameterIndex, long x) throws SQLException {
        parameters.getIndexToSetParameterMethodAndArgsMap().put(parameterIndex, new SetParameterMethodAndArgs(SetParameterMethod.setLong, new Object[]{parameterIndex, x}));

    }

    public void setString(int parameterIndex, String x) throws SQLException {
        parameters.getIndexToSetParameterMethodAndArgsMap().put(parameterIndex, new SetParameterMethodAndArgs(SetParameterMethod.setString, new Object[]{parameterIndex, x}));
    }

    public void setFloat(int parameterIndex, float x) throws SQLException {
        parameters.getIndexToSetParameterMethodAndArgsMap().put(parameterIndex, new SetParameterMethodAndArgs(SetParameterMethod.setFloat, new Object[]{parameterIndex, x}));

    }

    public void setDouble(int parameterIndex, double x) throws SQLException {
        parameters.getIndexToSetParameterMethodAndArgsMap().put(parameterIndex, new SetParameterMethodAndArgs(SetParameterMethod.setDouble, new Object[]{parameterIndex, x}));

    }

    // 这里ustore底层将date按long存储

    public void setDate(int parameterIndex, Date x) throws SQLException {
        parameters.getIndexToSetParameterMethodAndArgsMap().put(parameterIndex, new SetParameterMethodAndArgs(SetParameterMethod.setDate, new Object[]{parameterIndex, x}));
    }

    public void clearParameters() throws SQLException {
        this.parameters.getIndexToSetParameterMethodAndArgsMap().clear();
    }

    public void setNull(int parameterIndex, int sqlType) throws SQLException {
        parameters.getIndexToSetParameterMethodAndArgsMap().put(parameterIndex, new SetParameterMethodAndArgs(SetParameterMethod.setNull1, new Object[]{parameterIndex, null}));
    }

    public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
        parameters.getIndexToSetParameterMethodAndArgsMap().put(parameterIndex, new SetParameterMethodAndArgs(SetParameterMethod.setBigDecimal, new Object[]{parameterIndex, x}));
    }

    public void setTime(int parameterIndex, Time x) throws SQLException {
        parameters.getIndexToSetParameterMethodAndArgsMap().put(parameterIndex, new SetParameterMethodAndArgs(SetParameterMethod.setTime, new Object[]{parameterIndex, x}));
    }

    public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
        parameters.getIndexToSetParameterMethodAndArgsMap().put(parameterIndex, new SetParameterMethodAndArgs(SetParameterMethod.setTimestamp, new Object[]{parameterIndex, x}));
    }

    public void setObject(int parameterIndex, Object x) throws SQLException {
        parameters.getIndexToSetParameterMethodAndArgsMap().put(parameterIndex, new SetParameterMethodAndArgs(SetParameterMethod.setObject, new Object[]{parameterIndex, x}));

    }

    public void addBatch() throws SQLException {
        parameters.addBatch();
    }

    public void addBatch(String sql) throws SQLException {
        throw new UnsupportedOperationException("addBatch(String chars) is not supported, please use addBatch() in PreparedParseAndExecute");
    }

    /**
     * 执行的顺序可能与传进来的顺序不同，因此返回值无意义
     */

    public int[] executeBatch() throws SQLException {
        int affectrows = this.executeUpdate();
        this.moreResults = false;
        return new int[]{affectrows};
    }

    public void clearBatch() throws SQLException {
        checkClosed();
        parameters = new Parameters();
    }

    public void setClob(int parameterIndex, Clob x) throws SQLException {
        parameters.getIndexToSetParameterMethodAndArgsMap().put(parameterIndex, new SetParameterMethodAndArgs(SetParameterMethod.setClob, new Object[]{parameterIndex, x}));
    }

    public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
        parameters.getIndexToSetParameterMethodAndArgsMap().put(parameterIndex, new SetParameterMethodAndArgs(SetParameterMethod.setNullWithTypeName, new Object[]{parameterIndex, null, typeName}));
    }

    public int getAutoGeneratedKeys() {
        return autoGeneratedKeys;
    }

    public void setAutoGeneratedKeys(int autoGeneratedKeys) {
        this.autoGeneratedKeys = autoGeneratedKeys;
    }

}
